package com.yc.thread;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @program: concurrent
 * @description: sleep与wait方法在锁上的区别
 * @author: zy
 * @create: 2022-01-10 11:47
 */
public class Test11_sleep_wait_lock {
    /**
     * 此方法会被 n个线程来调用,会发生争抢， 同时只能一个线程进行执行.
     * sleep()方法不会释放锁，因此线程是按照先后顺序执行的。
     * synchronized的作用： 加锁
     */
    //   public void run(){}
//    public  synchronized void sleepMethod() {   // synchronized  ->　　Test11_sleep_wait_lock的对象的锁
//        System.out.println(printDate() + Thread.currentThread().getName() + "休眠1s");
//        try {
//            Thread.sleep(1000);   // 不会释放锁。
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        System.out.println(printDate() + Thread.currentThread().getName() + "休眠结束");
//    }

    /**
     * wait()方法会释放锁，因此一旦调用wait()方法就会造成其他线程运行
     *    同步方法
     */
    public   void waitMethod() {   //    TODO:  public synchronized void waitMethod()
        System.out.println(printDate() + Thread.currentThread().getName() + "等待1s");
        synchronized (this) {   //细粒度   同步块
            try {
               this. wait(1000);  //释放锁   wait与sleep的区别
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
       }
        System.out.println(printDate() + Thread.currentThread().getName() + "等待结束");
    }

    public static void main(String[] args) {
//        final Test11_sleep_wait_lock test1 = new Test11_sleep_wait_lock();  //new一次，一个对象， 一把锁.
//        for (int i = 0; i < 5; i++) {
//            // 不推荐直接创建线程。限于篇幅，这里直接创建线程。
//            // 推荐使用线程池管理线程。   Runnable是支持函数式编程的接口
//            //             Runnable对象   void run();
//            //                           void sleepMethod()
//            new Thread(   test1::sleepMethod    ).start();
//
////            new Thread(   new Runnable(){
////                @Override
////                public void run() {
////                    test1.sleepMethod();
////                }
////            }).start();
//        }


              /////////////测试另一种情况:   wait
//
//        System.out.println("--------------分割线--------------");
        final Test11_sleep_wait_lock test2 = new Test11_sleep_wait_lock();

        for (int i = 0; i < 5; i++) {
            // 不推荐直接创建线程。限于篇幅，这里直接创建线程。
            // 推荐使用线程池管理线程。
            new Thread(test2::waitMethod).start();
        }

    }

    private static String printDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date()) + " ";
    }
}